const { takeRight } = require("lodash");
const MyPromise = require("./my-promise");

const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

MyPromise.prototype.then1 = function (onFulfilled, onRejected) {
  let realOnFulfilled = onFulfilled;
  if (typeof onFulfilled !== 'function') {
    realOnFulfilled = (value) => {
      return value;
    }
  }
  let realOnRejected = onRejected
  if (typeof onRejected !== 'function') {
    realOnRejected = (reason) => {
      throw reason
    }
  }
  const that = this;
  if (that.status === FULFILLED) {
    const promise2 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        try {
          if (typeof onFulfilled !== 'function') {
            resolve(that.value)
          } else {
            const x = realOnFulfilled(that.value)
            resolvePromise(promise2, x, resolve, reject)
          }
        } catch (error) {
          reject(error)
        }
      }, 0)
    })
    return promise2
  }
  if (this.status === REJECTED) {
    const promise2 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        try {
          if (typeof onRejected !== 'function') {
            reject(that.reason)
          } else {
            const x = realOnRejected(that.reason)
            resolvePromise(promise2, x, resolve, reject)
          }
        } catch (error) {
          reject(error)
        }
      }, 0)
    })
    return promise2
  }

  if (that.status === PENDING) {
    const promise2 = new Promise((resolve, reject) => {
      that.onFullfilledCallbacks.push(() => {
        setTimeout(() => {
          try {
            if (typeof onFulfilled !== 'function') {
              resolve(that.value)
            } else {
              const x = realOnFulfilled(that.value)
              resolvePromise(promise2, x, resolve, reject)
            }
          } catch (error) {
            reject(error)
          }
        }, 0)
      })
      that.onRejectedCallbacks.push(() => {
        setTimeout(() => {
          try {
            if (typeof onRejected !== 'function') {
              reject(that.reason)
            } else {
              const x = realOnRejected(that.reason)
              resolvePromise(promise2, x, resolve, reject)
            }
          } catch (error) {
            reject(error)
          }
        }, 0)
      })
    })
    return promise2;
  }
}

MyPromise.prototype.then2 = function (onFulfilled, onRejected) {
  const that = this;
  if (that.status === FULFILLED) {
    const promise2 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        try {
          if (typeof onFulfilled !== 'function') {
            resolve(that.value)
          } else {
            const x = realOnFulfilled(that.value)
            resolvePromise(promise2, x, resolve, reject)
          }
        } catch (error) {
          reject(error)
        }
      }, 0)
    })
    return promise2;
  }
  if (that.status === REJECTED) {
    const promise2 = new MyPromise((resolve, reject) => {
      setTimeout(() => {
        try {
          if (typeof onRejected !== 'function') {
            reject(that.reason)
          } else {
            const x = realOnRejected(that.reason)
            resolvePromise(promise2, x, resolve, reject)
          }
        } catch (error) {
          reject(error)
        }
      }, 0)
    })
    return promise2
  }
  if (that.status === PENDING) {
    const promise2 = new MyPromise((resolve, reject) => {
      that.onFullfilledCallbacks.push(() => {
        setTimeout(() => {
          try {
            if (typeof onFulfilled !== 'function') {
              resolve(that.value)
            } else {
              const x = realOnFulfilled(that.reason)
              resolvePromise(promise2, x, resolve, reject)
            }
          } catch (error) {
            reject(error)
          }
        }, 0)
      })
      that.onRejectedCallbacks.push(() => {
        setTimeout(() => {
          try {
            if (typeof onRejected !== 'function') {
              reject(that.reason)
            } else {
              const x = realOnRejected(that.reason)
              resolvePromise(promise2, x, resolve, reject)
            }
          } catch (error) {
            reject(error)
          }
        }, 0)
      })
    })
    return promise2
  }
}